package com.security.config.security.authentication.username;

import com.security.config.security.authentication.common.MyLoginFailureHandler;
import com.security.config.security.authentication.common.MyLoginSuccessHandler;
import com.security.service.impl.AccountServiceImpl;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;

/**
 * 用户名密码认证配置
 * 指定登录路径、登录方式、登录成功处理器、登录失败处理器、认证提供者
 * 配置父类 AuthenticationManager
 *
 * @author DblSun
 */
public class UsernameAuthenticationConfigurer extends AbstractHttpConfigurer<UsernameAuthenticationConfigurer, HttpSecurity> {

    private final BCryptPasswordEncoder bCryptPasswordEncoder;
    private final AccountServiceImpl accountService;
    private final StringRedisTemplate stringRedisTemplate;

    public UsernameAuthenticationConfigurer(AccountServiceImpl accountService,
                                            BCryptPasswordEncoder bCryptPasswordEncoder,
                                            StringRedisTemplate stringRedisTemplate) {
        this.accountService = accountService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
        this.stringRedisTemplate = stringRedisTemplate;
    }


    @Override
    public void configure(HttpSecurity builder) {
        RequestMatcher requestMatcher = new AntPathRequestMatcher("/username/login", "POST", true);
        AuthenticationManager localAuthenticationManager = builder.getSharedObject(AuthenticationManager.class);
        UsernameAuthenticationFilter usernameAuthenticationFilter =
                new UsernameAuthenticationFilter(requestMatcher, localAuthenticationManager);
        usernameAuthenticationFilter.setAuthenticationSuccessHandler(new MyLoginSuccessHandler(stringRedisTemplate));
        usernameAuthenticationFilter.setAuthenticationFailureHandler(new MyLoginFailureHandler());
        builder.authenticationProvider(new UsernameAuthenticationProvider(accountService, bCryptPasswordEncoder))
                .addFilterBefore(usernameAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
    }
}
